const { ccclass, property } = cc._decorator;
import MonstersBilder from './MonstersBilder';
import MonsterControl from './MonsterControl';
import SkillBlast from './SkillBlast';
import SkillTransfer from './SkillTransfer';
import SkillStrike from './SkillStrike';
import kdaControl from '../Play/kdaControl';
import MonsterPortal from './MonsterPortal';
import SkillBuild from '../SkillBuild/SkillBuild';
import MonsterTarget from '../SkillBuild/MonsterTarget';
import RandomProp from '../RandomProp/RandomPropControl';
import SoundMgr from '../SoundMgr';

@ccclass
export default class MonstersBilderControl extends cc.Component {
    @property(cc.Node)
    SoundNode: cc.Node = null;
    @property(cc.Node)
    MStatusPool: cc.Node = null;
    @property(cc.Node)
    MRefreshPool: cc.Node = null;
    @property(cc.String)
    MonsterPortalRoot: string = "Portal/";
    @property(cc.String)
    MonsterBlastsRoot: string = "Monsters/Blasts/";
    @property(cc.String)
    MonsterSkillsRoot: string = "Monsters/Skills/";
    @property(cc.String)
    MonsterBilder: string[] = [];//初始怪兽生成器
    @property(cc.Node)
    ObjectNode: cc.Node = null;
    @property(cc.Node)
    WorldNode: cc.Node = null;
    @property(cc.Node)
    playSkillsNode: cc.Node = null;
    @property(cc.Node)
    MonsterNode: cc.Node = null;
    @property(cc.Node)
    SkillBuildNode: cc.Node = null;
    @property(cc.Node)
    RandomPropNode: cc.Node = null;
    Blasts: any = null;
    Strike: any = null;
    MonsterPrefab: Map<string, cc.Prefab> = null;
    MonsterAtlas: Map<string, cc.SpriteAtlas> = null;
    BlastList: Map<string, cc.Node> = new Map<string, cc.Node>();
    SkillsNodeControl: kdaControl = null;
    SkillBuildControl: SkillBuild = null;

    _RandomProp: RandomProp = null;
    _SoundMgr: SoundMgr = null;

    onLoad() {
        this.SkillsNodeControl = this.playSkillsNode.getComponent(kdaControl);
        this.SkillBuildControl = this.SkillBuildNode.getComponent(SkillBuild);
        this._SoundMgr = this.SoundNode.getComponent(SoundMgr);
    }
    start() {
        let self = this;
        this.MonsterBilder.forEach(element => {
            self.loadMonsterBilder(element);
        });
    }
    loadMonsterBilder(Bilder: string): any {
        let path = this.MonsterPortalRoot + Bilder;
        let self = this;
        cc.resources.load(path, function (err, jsonAsset) {
            if (err) {
                cc.log(err);
                return;
            }
            let _json = (jsonAsset as cc.JsonAsset).json;

            _json.Bilders.forEach(element => {
                var portal = self.getPortal(element.Portal, _json.Portals, self.MonsterNode);
                if (portal) {
                    self.initBilder(portal, element);
                }
            });
        });
    }
    getPortal(id: string, Portals: any, MonsterNode: cc.Node): cc.Node {
        for (let i = 0; i < Portals.length; i++) {
            if (id == Portals[i].Id) {
                let Portal = Portals[i];
                let WarpPortal = this.MonsterAtlas.get("WarpPortal.plist");
                let sprite = WarpPortal.getSpriteFrame(Portal.SpriteName);
                let newNode = cc.instantiate(this.MonsterPrefab.get("Portal"));
                let door = newNode.getChildByName("door");
                if (sprite && door) {
                    door.getComponent(cc.Sprite).spriteFrame = sprite;
                }
                let control = newNode.getComponent(MonsterPortal);
                control.PortalJson = Portal;
                control.MonsterNode = MonsterNode;
                return newNode;
            }
        }
    }
    initBilder(Portal: cc.Node, Bilder: any) {
        let newNode = new cc.Node();
        newNode.group = this.node.group;
        let control = newNode.addComponent(MonstersBilder);
        control.BilderControl = this;
        control.MonsterNode = this.MonsterNode;
        control.ObjectNode = this.ObjectNode;
        control.WorldNode = this.WorldNode;
        control.Monster = this.getMonster(Bilder);
        if (Bilder.Skills) {
            control.skills = Bilder.Skills;
            control.SkillBuildControl = this.SkillBuildControl;
        }
        if (Bilder.Blast) {
            this.setBlast(Bilder.Blast, control.Monster);
        }
        let controlPortal = Portal.getComponent(MonsterPortal);
        controlPortal.monstersBilder = control;
        newNode.addChild(Portal);
        this.MonsterNode.addChild(newNode);
    }
    getMonster(Bilder: any): cc.Node {
        let newNode = cc.instantiate(this.MonsterPrefab.get("MonsterBody"));
        newNode.name = Bilder.Name;
        newNode.group = this.node.group;
        let spriteBody = newNode.getChildByName("Body").getComponent(cc.Sprite);
        let MonstersIcon = this.MonsterAtlas.get("Monsters.plist");
        spriteBody.spriteFrame = MonstersIcon.getSpriteFrame(Bilder.Sprite);
        if (!this._RandomProp)
            this._RandomProp = this.RandomPropNode.getComponent(RandomProp);
        let control = newNode.getComponent(MonsterControl);
        control.life = Bilder.Life;
        control.attackDamage = Bilder.AttackDamage;
        control.jumpTime = Bilder.JumpInterval;
        control.jumpHeight = Bilder.JumpY;
        control.jumpLong = Bilder.JumpX;
        control.isTrace = Bilder.IsTrace;
        control.canOutWay = Bilder.CanOutWay;
        control.attribute = Bilder.Attribute;
        control._RandomProp = this._RandomProp;
        control._SoundMgr = this._SoundMgr;
        if (Bilder.Transfer > 0) {
            let trans = this.MonsterPrefab.get("Transfer");
            if (trans) {
                let transNode = cc.instantiate(trans);
                transNode.name = "Transfer";
                let transControl = transNode.getComponent(SkillTransfer);
                let waysNode = this.ObjectNode;
                transControl.wayObject = waysNode;
                transControl.MonsterBody = newNode;
                transControl.interval = Bilder.Transfer;
                newNode.getChildByName("Skills").addChild(transNode);
            }
        }
        if (Bilder.Strike) {
            let param = null;
            for (let i = 0; i < this.Strike.length; i++) {
                let element = this.Strike[i];
                if (element.Id == Bilder.Strike) {
                    param = element;
                    break;
                }
            }
            let strike = this.MonsterPrefab.get("Strike");
            if (strike && param) {
                let _node = newNode.getChildByName("Skills");
                let strikeNode = cc.instantiate(strike);
                strikeNode.group = _node.group;
                let strikeControl = strikeNode.getComponent(SkillStrike);
                strikeControl._MonsterBody = newNode;
                strikeControl.speed = param.Speed;
                strikeControl.interval = param.Interval;
                strikeControl.desArmor = param.DesArmor;
                strikeControl.addDamage = param.AddDamage;
                _node.addChild(strikeNode);
            }
        }
        let controlAttack = newNode.getComponent(MonsterTarget);
        controlAttack.StatusPool = this.MStatusPool;
        controlAttack.RefresPool = this.MRefreshPool;
        controlAttack._MonsterControl = control;
        return newNode;
    }
    setBlast(BlastId: string, Monster: cc.Node) {
        if (this.BlastList.has(BlastId)) {
            let node = Monster.getChildByName("Skills");
            let blast = this.BlastList.get(BlastId);
            let addNode = cc.instantiate(blast);
            let addcontrol = addNode.getComponent(SkillBlast);
            addcontrol._MonsteRoot = Monster;
            addcontrol.init();
            node.addChild(addNode);
        }
        else {
            for (let i = 0; i < this.Blasts.length; i++) {
                let element = this.Blasts[i];
                if (element.Id == BlastId) {
                    this.loadBlast(element, Monster);
                    return;
                }
            }
        }
    }
    loadBlast(Blast: any, maonster: cc.Node) {
        let newNode = new cc.Node();
        newNode.name = "Blast"
        let control = newNode.addComponent(SkillBlast)
        control.skillName = Blast.Id;
        control.area = Blast.Area;
        control.sample = Blast.Sample;
        control.addDamage = Blast.AddDamage;
        let self = this;
        cc.resources.load(this.MonsterBlastsRoot + Blast.Sprite, cc.SpriteAtlas, function (err, atlas) {
            if (err) {
                cc.log(err);
                return;
            }
            let _node = maonster.getChildByName("Skills");
            newNode.group = _node.group;
            control.StatusSprite = (atlas as cc.SpriteAtlas).getSpriteFrames();
            self.BlastList.set(Blast.Id, newNode);

            let addNode = cc.instantiate(newNode);
            let addcontrol = addNode.getComponent(SkillBlast);
            addcontrol._MonsteRoot = maonster;
            addcontrol.init();
            _node.addChild(addNode);
        });
    }
    getSprites(sprites: cc.SpriteFrame[], name: string): cc.SpriteFrame[] {
        let sprits: Array<cc.SpriteFrame> = new Array<cc.SpriteFrame>();
        for (let i = 0; i < sprites.length; i++) {
            if (sprites[i].name.charAt(0) == name) {
                sprits.push(sprites[i]);
            }
        }
        return sprits;
    }
}
